变量、函数
- 函数名称大写则包外可见,小写不可见
- 变量声明未赋值时是零值,数字是0,布尔是false,字符串是””,接口和引用类型是nil(slice、指针、map、通道、函数)
- 短变量声明语句中,只需要声明至少一个新变量即可:
1 | a := 1 |
类型转换分为强制类型转换及类型断言
强制类型转换格式为T(x)
1
2
3
4
5
6
7
8
9// 基本类型转换
var a int32 = 1
var b int64 = int64(a)
var c float64 = 12.3
var d float32 = float32(c) // 丢精度
// 指针类型
var a int = 10
var p *int = &a
var c *int64 = (*int64)(unsafe.Pointer(b)) // 需要借助unsafe包类型断言
1
2
3
4
5
6
7
8
9
10
11
12
13// x.(type),仅限于switch语句
var a interface{} = 10
switch a.(type) {
case int:
fmt.Println("int")
case float32:
fmt.Println("float32")
}
// 类型转换检验
var a interface{} = 10
if t, ok := a.(int); ok {
fmt.Println("int ", t)
}
内置new(T)函数作用:初始化变量,并返回其指针;与局部变量声明没区别,为了分配内存
- 包初始化init()函数:不能被调用,按照每个包的声明顺序执行
- 字符串相关标准包:strings搜索替换比较切分等;bytes与strings类似但作用于字节slice;strconv用于字符串与其他类型的转换;unicode判断文字特性如大小写、是否为数字等
slice、map、chan
- slice三属性:指针、长度、容量;指针指向第一个可访问的元素;长度指slice中元素个数,len获取;容量指slice的底层数组的长度,cap获取
- 严格来说golang中没有引用传递,只有值传递以及“使用引用作为值”的值传递
- 数组作为函数参数时是值传递,使用其指针可以认为是传递引用值;slice本身包含指针,因此传递引用值
1 | arr := [3]int{1,2,3} |
- map和channel的传递也是值传递
1 | m := map[string]int{"a": 1} |
- slice、map、channel一定要make来初始化的原因:均含有指针属性,只声明的话变量都是nil
1 | var s []int // nil |
错误处理
- 错误处理要自己建立,利用panic、recover和defer
- defer是后进先出,且defer在return后、函数出栈前执行,因此可以改变返回值
- handler实现
1 | func main() { |
- Try-Catch实现
1 | /* |
方法、接口
- 函数vs方法:方法多了一个接收者,表示该方法与此接收者类型绑定;值接收者不能改变原来的类型变量,指针接收者可以改变
- 接口即约定,是一组包含方法名、参数、返回值但无具体实现的方法的集合
- 实现接口的所有方法则认为实现了接口,无需显式声明
- 示例
1 | type MyInterface interface { |
- 接口断言判断类型是否实现了某接口
1 | // 使用特殊的接口断言x.(T),判断是否实现了接口 |
- 空接口不包含任何方法的接口,所有类型都实现了空接口,因此可以用来存储任何类型的数值
- 接口零值是nil
- 接口嵌套
1 | type MyInterface interface { |
- 接口用途之一:类型变量初始化
1 | type People interface { |